package com.dj.mingkong.common.infrastructure.base.repository.impl;

import com.dj.mingkong.common.enums.DeleteEnum;
import com.dj.mingkong.common.infrastructure.base.dto.query.QueryVo;
import com.dj.mingkong.common.infrastructure.base.eo.BaseMgEo;
import com.dj.mingkong.common.infrastructure.base.repository.BaseMongodbRepository;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.domain.Example;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;

import java.util.List;
import java.util.Optional;

/**
 * @author zenglonghui
 * @date: 2023/6/30 17:03
 */
@Slf4j
public class BaseMongodbRepositoryImpl<M extends BaseMongodbRepository<T, String>, T extends BaseMgEo, Q extends QueryVo> extends SimpleMongoRepository<T, String> implements BaseMongodbRepository<T, String> {
    protected final MongoOperations mongoTemplate;

    protected final MongoEntityInformation<T, String> entityInformation;

    private Class<T> clazz;


    public BaseMongodbRepositoryImpl(MongoEntityInformation<T, String> metadata, MongoOperations mongoOperations) {
        super(metadata, mongoOperations);
        this.mongoTemplate = mongoOperations;
        this.entityInformation = metadata;
        clazz = entityInformation.getJavaType();
    }

    @Override
    public void deleteById(@NotNull String id) {
        final Optional<T> optional = this.findById(id).filter(t -> DeleteEnum.NOT.equalsIntVal(t.getDeleted()));
        optional.ifPresent(t -> {
            t.setDeleted(DeleteEnum.DELETED.getIntVal());
            super.save(t);
        });
    }

    @Override
    public void delete(@NotNull T entity) {
        entity.setDeleted(DeleteEnum.NOT.getIntVal());
        final Example<T> example = Example.of(entity);
        final List<T> all = this.findAll(example);
        if (!all.isEmpty()) {
            all.forEach(t -> t.setDeleted(DeleteEnum.DELETED.getIntVal()));
            super.saveAll(all);
        }
    }

    @Override
    public void deleteAll() {
        final List<T> all = this.findAll().stream().filter(t -> DeleteEnum.NOT.equalsIntVal(t.getDeleted())).toList();
        if (!all.isEmpty()) {
            all.forEach(t -> t.setDeleted(DeleteEnum.DELETED.getIntVal()));
            super.saveAll(all);
        }
    }

    @Override
    public void deleteAll(@NotNull Iterable<? extends T> entities) {
        entities.forEach(this::delete);
    }

    @Override
    public void deleteAllById(@NotNull Iterable<? extends String> ids) {
        ids.forEach(this::deleteById);
    }

}
